package com.gwt.boot.tools;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.gwt.boot.exception.BusinessException;
import com.gwt.cloud.constant.ApiResultEnum;
import lombok.extern.log4j.Log4j2;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Log4j2
public class ApiTools {

    /**
     * 发送GET请求到指定的URL，并包含查询参数
     *
     * @param url    请求的URL
     * @param params 查询参数
     * @return 响应结果
     * @throws IOException 如果请求失败
     */
    public static <T> T sendGetRequest(String url, Map<String, String> params, Class<T> clazz) {
        HttpClient client = HttpClients.createDefault();
        HttpGet request = new HttpGet(buildUrlWithQueryParams(url, params));
        HttpResponse response;
        try {
            response = client.execute(request);
        } catch (IOException e) {
            throw new BusinessException(ApiResultEnum.FAIL_OUT.getStatus(), ApiResultEnum.FAIL_OUT.getMessage());
        }
        // 检查响应状态码
        if (response.getStatusLine().getStatusCode() != ApiResultEnum.SUCCESS.getStatus()) {
            throw new BusinessException(ApiResultEnum.FAIL_OUT.getStatus(), ApiResultEnum.FAIL_OUT.getMessage());
        }
        try {
            // 读取响应数据
            String result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            return JSONObject.toJavaObject(JSONObject.parseObject(result), clazz);
        } catch (IOException e) {
            throw new BusinessException(ApiResultEnum.FAIL_OUT.getStatus(), ApiResultEnum.FAIL_OUT.getMessage());
        }
    }

    /**
     * 发送POST请求到指定的URL，并包含JSON体
     *
     * @param url    请求的URL
     * @param json   请求的JSON体
     * @return 响应结果
     * @throws IOException 如果请求失败
     */
    public static <T> T sendPostRequest(String url, String json, Class<T> clazz)  {
        HttpClient client = HttpClients.createDefault();
        HttpPost request = new HttpPost(url);
        StringEntity entity;
        try {
            entity = new StringEntity(json);
        } catch (UnsupportedEncodingException e) {
            throw new BusinessException(ApiResultEnum.FAIL_OUT.getStatus(), ApiResultEnum.FAIL_OUT.getMessage());
        }
        request.addHeader(new BasicHeader("Content-Type", "application/json"));
        request.setEntity(entity);
        HttpResponse response;
        try {
            response = client.execute(request);
        } catch (IOException e) {
            throw new BusinessException(ApiResultEnum.FAIL_OUT.getStatus(), ApiResultEnum.FAIL_OUT.getMessage());
        }
        // 检查响应状态码
        if (response.getStatusLine().getStatusCode() != ApiResultEnum.SUCCESS.getStatus()) {
            throw new BusinessException(ApiResultEnum.FAIL_OUT.getStatus(), ApiResultEnum.FAIL_OUT.getMessage());
        }
        // 读取响应数据
        //String output = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
        return BeanUtil.toBean(response.getEntity(), clazz);
    }

    /**
     * 将查询参数附加到URL上
     *
     * @param url    基础URL
     * @param params 查询参数
     * @return 带有查询参数的完整URL
     */
    private static String buildUrlWithQueryParams(String url, Map<String, String> params) {
        if (params == null || params.isEmpty()) {
            return url;
        }
        StringBuilder builder = new StringBuilder(url);
        if (!url.contains("?")) {
            builder.append("?");
        } else if (!url.endsWith("&")) {
            builder.append("&");
        }
        boolean isFirst = true;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (isFirst) {
                isFirst = false;
            } else {
                builder.append("&");
            }
            builder.append(entry.getKey()).append("=").append(entry.getValue());
        }
        return builder.toString();
    }
}